﻿using System;

namespace SpatialHashLib
{
    internal static class ArrayExtensions
    {
        public const int DefaultMaxSizeInc = 1024;

        public static T[] EnsureSize<T>(this T[] array, int size, int maxSizeInc)
        {
            if (size >= array.Length)
            {
                int newSize = array.Length == 0 ? 4 : array.Length * 2;

                if (newSize > maxSizeInc)
                    newSize = array.Length + maxSizeInc;

                T[] newArray = new T[newSize];
                array.CopyTo(newArray, 0);
                return newArray;
            }
            else
                return array;
        }

        public static T[] EnsureSize<T>(this T[] array, int size)
        {
            return EnsureSize(array, size, DefaultMaxSizeInc);
        }

        public static T[] Trim<T>(this T[] array, int amount)
        {
            if (amount <= 0)
                return array;

            if (amount >= array.Length)
                return new T[0];

            T[] newArray = new T[array.Length - amount];
            array.CopyTo(newArray, 0);
            return newArray;
        }

        public static int BinarySearch<T>(this T[] array, IComparable<T> value)
        {
            if (array == null || array.Length == 0)
                return -1;

            int min = 0;
            int max = array.Length - 1;
            int mid;
            int cmp = 0;

            while (min <= max)
            {
                mid = min + ((max - min) >> 1);
                cmp = value.CompareTo(array[mid]);

                if (cmp == 0)
                    return mid;

                if (cmp > 0)
                    min = mid + 1;
                else
                    max = mid - 1;
            }

            return ~min;
        }

        public static void Sort<T>(this T[] array)
        {
            Array.Sort<T>(array);
        }

        public static T[] Insert<T>(this T[] array, int index, T value)
        {
            T[] newArray = new T[array.Length + 1];
            Array.Copy(array, 0, newArray, 0, index);
            newArray[index] = value;
            Array.Copy(array, index, newArray, index + 1, array.Length - index);
            return newArray;
        }
    }
}
